package com.rcn.hibernate;

import com.rcn.domain.Paciente;
import java.util.List;
import org.hibernate.*;

/**
 *
 * @author Nicolas
 */
public class GestorBD {
    private static GestorBD gestor;


    private GestorBD(){
    }

    public static GestorBD getGestorBD(){
        if(gestor==null){
            gestor=new GestorBD();
        }
        return gestor;
    }

    /**
     * Guarda cualquier tipo de objecto a la base de datos.
     * @param <T>
     * @param item
     * @throws HibernateException
     */
    public <T> void  save(T item)throws HibernateException{
        Session session = HibernateUtil.getSession();
        try
        {
            session.beginTransaction();
            session.save(item);
            session.getTransaction().commit();
            HibernateUtil.getSession().close();
        }catch(HibernateException e){
            session.getTransaction().rollback();
            if(HibernateUtil.getSession()!=null)
                HibernateUtil.getSession().close();
            throw new HibernateException("Ocurrio un problema al guardar. "+e.getMessage());
        }
        
    }

    /**
     * Recupera cualquier tipo de objeto de la base de datos.
     * @param clase
     * @param id
     * @return
     */
    public Object getData(Class clase,String id){
        Session session = HibernateUtil.getSession();
        //El metodo get devuelve null cuando ninguna fila corresponde con el id.
        Object loadedObject = (Object)session.get(clase, Long.parseLong(id));
        return loadedObject;
    }

    /**
     *
     * @return
     * @throws DataAccessLayerException
     */
     public List getAll(String tablename){
        List events = null;
        Session session = HibernateUtil.getSession();
        org.hibernate.Query query = session.createQuery("from "+tablename);
        events =  query.list();
         
        return events;
    }

     /**
      * Actualiza un registro de la base de datos.
      * @param <T>
      * @param item
      */
     public <T> void update(T item)throws HibernateException{
         Session session=HibernateUtil.getSession();
         try
         {
             session.beginTransaction();
             session.update(item);
             session.getTransaction().commit();
             HibernateUtil.getSession().close();
         }catch(HibernateException e){
            session.getTransaction().rollback();
            if(HibernateUtil.getSession()!=null)
                HibernateUtil.getSession().close();
            throw new HibernateException("Ocurrio un problema al actualizar. "+e.getMessage());
        }
     }

     /**
      * Guarda o actualiza un registro en la bd.
      * @param <T>
      * @param item
      * @throws HibernateException arda 
      */
     public <T> void saveOrUpdate(T item)throws HibernateException{
         Session session=HibernateUtil.getSession();
         try
         {
             session.beginTransaction();
             session.saveOrUpdate(item);
             session.getTransaction().commit();
             session.close();
         }catch(HibernateException e){
            session.getTransaction().rollback();
            if(session!=null)
                session.close();
            throw new HibernateException("Ocurrio un problema al guardar o actualizar. "+e.getMessage());
        }
     }
     
     public <T> void saveOrUpdate(T item,Session s)throws HibernateException{
         try
         {
            s.saveOrUpdate(item);
         }catch(HibernateException e){
            throw new HibernateException("Ocurrio un problema al guardar o actualizar. "+e.getMessage());
        }
     }
     /**
      * Borra un registro de la base de datos.
      * @param <T>
      * @param item
      */
     public <T> void delete(T item)throws HibernateException{
         Session session=HibernateUtil.getSession();
         try{
             session.beginTransaction();
             session.delete(item);
             session.getTransaction().commit();
             HibernateUtil.getSession().close();
         }catch(HibernateException e){
            session.getTransaction().rollback();
            if(HibernateUtil.getSession()!=null)
                HibernateUtil.getSession().close();
            throw new HibernateException("Ocurrio un problema al borrar. "+e.getMessage());
        }
     }
     
     /**
      * Ejecuta una query determinada en la bd.
      * @param <T>
      * @param item
      * @param q
      * @return 
      */
     public <T> List<T> executeQuery(String q){
         
         Session session=HibernateUtil.getSession();
         Query query = session.createQuery(q);
         List<T> results=null;
         try{
             session.beginTransaction();    
             results=query.list();
             session.getTransaction().commit();
         }catch(HibernateException e){
            session.getTransaction().rollback();
            if(HibernateUtil.getSession()!=null)
                HibernateUtil.getSession().close();
            throw new HibernateException("Ocurrio un problema al intentar ejecutar: "+q+". "+e.getMessage());
        }finally{
             HibernateUtil.getSession().close();
         }
         return results;
     }
     
     public int executeUpdateQuery(String q , Session s){
         Query query = s.createQuery(q);
         int result = 0;
         try{  
             result = query.executeUpdate();
         }catch(HibernateException e){
            throw new HibernateException("Ocurrio un problema al intentar ejecutar: "+q+". "+e.getMessage());
         }
         return result;
     }
     
     public int executeUpdateQuery(String q){
         Session session=HibernateUtil.getSession();
         Query query = session.createQuery(q);
         int result = 0;
         try{
             session.beginTransaction();    
             result=query.executeUpdate();
             session.getTransaction().commit();
         }catch(HibernateException e){
            session.getTransaction().rollback();
            if(HibernateUtil.getSession()!=null)
                HibernateUtil.getSession().close();
            throw new HibernateException("Ocurrio un problema al intentar ejecutar: "+q+". "+e.getMessage());
        }finally{
             HibernateUtil.getSession().close();
         }
         return result;
     }
}
